package com.gioneco.util;

import com.gioneco.model.PageResultVO;
import com.gioneco.util.esCondition.ConversionDoUtil;
import com.gioneco.util.esCondition.Query;
import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * es 高级查询工具类
 * @author dongjialin
 */
@Component
public class EsLambdaQueryUtil {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 高级查询 /分页查询一套式解决方案
     * @param query  查询条件
     * @param t 返回对象 此对象必须是带有 @Document(indexName = "")
     */
    public <T,K> PageResultVO<K> selectQueryByPage(Query<K> query, T t) {
        NativeSearchQuery build = getNativeSearchQuery(query);
        Class clazz = (Class) t;
        SearchHits<K> searchHits = elasticsearchRestTemplate.search(build,clazz);
        return ConversionDoUtil.pagingHandler(searchHits,query);
    }


    /**
     * 高级查询 /分组查询一套式解决方案
     * @param query  查询条件
     * @param t 返回对象 此对象必须是带有 @Document(indexName = "")
     */
    public <T,K>Map<String, Long> selectQueryGroupByOneField(Query<K> query, T t) {
        NativeSearchQuery build = getNativeSearchQuery(query);
        Class clazz = (Class) t;
        SearchHits<K> search = elasticsearchRestTemplate.search(build,clazz);
        Map<String, Long> result = new LinkedHashMap<>();
        if(search.getAggregations() == null){
            return result;
        }
        //得到聚合函数
        Aggregations aggregations = search.getAggregations();
        //得到上面设置的分组
        Terms  terms = aggregations.get(query.criteria.aggregationFieldName);
        //得到这个聚合的List对象
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        if(!CollectionUtils.isEmpty(buckets))
        buckets.forEach(e-> result.put(e.getKeyAsString(),e.getDocCount()));
        return result;
    }

    /**
     * @param query 查询对象集合
     * @return 返回 List 集合数据
     */
    public <T,K>List<K> selectList(Query<K> query, T t) {
        NativeSearchQuery build = getNativeSearchQuery(query);
        Class clazz = (Class) t;
        SearchHits<K> searchHits = elasticsearchRestTemplate.search(build,clazz);
        return ConversionDoUtil.list(searchHits);
    }


    public <K> NativeSearchQuery getNativeSearchQuery(Query<K> query){
        return query.nativeSearchQueryBuilder.build();
    }
}
